package com.example.service.user.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.example.config.ProjectProperties;
import com.example.dto.request.PageRequestDTO;
import com.example.dto.request.user.CommunityDynamicRequestDTO;
import com.example.exception.db.DeleteException;
import com.example.exception.InsertException;
import com.example.exception.community.DynamicNotExistException;
import com.example.mapper.PublisherMapper;
import com.example.mapper.UserDynamicMapper;
import com.example.mapper.UserDynamicPictureMapper;
import com.example.pojo.UserDynamic;
import com.example.pojo.UserDynamicPicture;
import com.example.service.user.CommunityDynamicService;
import com.example.dto.business.UserDynamicBusinessDTO;
import com.example.vo.user.Publisher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @author LeXin Huang
 * @date 2021年03月23日 14:18
 */
@Slf4j
@Service
public class CommunityDynamicServiceImpl extends ServiceImpl<UserDynamicMapper, UserDynamic>
        implements CommunityDynamicService {

    private final UserDynamicPictureMapper userDynamicPictureMapper;

    private final PublisherMapper publisherMapper;

    private final String FILE_RESOURCE_PATH_SEPARATOR;

    private final String IMAGE_DIRECTORY_PATH;

    private final String[] SUPPORTED_IMAGE_TYPES;

    private final String IMAGE_URL_PREFIX;

    public CommunityDynamicServiceImpl(UserDynamicPictureMapper userDynamicPictureMapper, PublisherMapper publisherMapper,
                                       ProjectProperties projectProperties) {
        this.userDynamicPictureMapper = userDynamicPictureMapper;
        this.publisherMapper = publisherMapper;
        this.IMAGE_DIRECTORY_PATH = projectProperties.getDynamic().getImage().getDirectoryPath();
        this.FILE_RESOURCE_PATH_SEPARATOR = projectProperties.getFile().getResourcePathSeparator();
        this.SUPPORTED_IMAGE_TYPES = projectProperties.getDynamic().getImage().getSupportedTypes();
        this.IMAGE_URL_PREFIX = projectProperties.getDynamic().getImage().getUrlPrefix();
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addDynamic(Integer userId, CommunityDynamicRequestDTO dynamicRequestDTO) {

        UserDynamic dynamic = new UserDynamic();
        dynamic.setUserId(userId);
        dynamic.setContent(dynamicRequestDTO.getContent());
        dynamic.setTopic(dynamicRequestDTO.getTopic());
        if (!save(dynamic)) {
            throw new InsertException("出错了!发布动态失败!");
        }
        List<String> imagesUrl = upload(dynamicRequestDTO.getPictures());
        for (String imageUrl : imagesUrl) {
            UserDynamicPicture dynamicPicture = new UserDynamicPicture();
            dynamicPicture.setDynamicId(dynamic.getId());
            dynamicPicture.setUrl(imageUrl);
            boolean saveSuccess = save(dynamicPicture);
            if (!saveSuccess) {
                throw new InsertException("出错啦, 上传图片失败!");
            }
        }
    }

    private boolean save(UserDynamicPicture userDynamicPicture) {
        return SqlHelper.retBool(userDynamicPictureMapper.insert(userDynamicPicture));
    }

    @Override
    public List<UserDynamicBusinessDTO> getHistoryDynamics(Integer userId, PageRequestDTO pageRequestDTO) {
        List<UserDynamic> dynamics = baseMapper.selectHistoryDynamics(pageRequestDTO.getOffset(), pageRequestDTO.getSize());
        return transformIntoDTOList(userId, dynamics);
    }

    @Override
    public List<UserDynamicBusinessDTO> getLatestDynamics(Integer userId, Integer currentDynamicId) {
        List<UserDynamic> dynamics = baseMapper.selectLatestDynamics(currentDynamicId);
        return transformIntoDTOList(userId, dynamics);
    }

    @Override
    public List<UserDynamicBusinessDTO> getUserHistoryDynamics(Integer visitorId, Integer respondentId,
                                                               PageRequestDTO pageDTO) {
        List<UserDynamic> dynamics = baseMapper.selectUserHistoryDynamics(respondentId, pageDTO.getOffset(),
                pageDTO.getSize());
        return transformIntoDTOList(visitorId, dynamics);
    }

    private List<UserDynamicBusinessDTO> transformIntoDTOList(Integer visitorId, List<UserDynamic> queryRes) {
        if (null == queryRes) {
            return Collections.emptyList();
        }
        List<UserDynamicBusinessDTO> res = new ArrayList<>();
        for (UserDynamic dynamic : queryRes) {
            UserDynamicBusinessDTO dynamicBusinessDTO = new UserDynamicBusinessDTO(dynamic);
            dynamicBusinessDTO.setIsMineDynamic(dynamic.getPublisher().getUserId().equals(visitorId));
            res.add(dynamicBusinessDTO);
        }
        return res;
    }

    @Override
    public UserDynamicBusinessDTO getById(Integer id) {
        UserDynamic queryRes = baseMapper.selectById(id);
        if (null == queryRes) {
            throw new DynamicNotExistException("该动态不存在!");
        }
            List<String> picturesUrl = Objects.requireNonNullElse(
                    userDynamicPictureMapper.selectByDynamicId(queryRes.getId()),
                    Collections.emptyList());
            Publisher publisher = Objects.requireNonNullElse(publisherMapper.selectById(queryRes.getUserId()),
                                                            new Publisher());
            queryRes.setPublisher(publisher);
            queryRes.setPicturesUrl(picturesUrl);
        return new UserDynamicBusinessDTO(queryRes);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void remove(UserDynamicBusinessDTO dynamicBusinessDTO) {
        for (String fileUrl : dynamicBusinessDTO.getPicturesUrl()) {
            boolean deleteSuccess = deleteFileByUrl(fileUrl);
            if (!deleteSuccess) {
                log.info("删除文件: " + fileUrl + " 失败!");
            }
        }
        boolean deleteFailed = !removeById(dynamicBusinessDTO.getDynamicId());
        if (deleteFailed) {
            throw new DeleteException("出错了!删除动态失败!");
        }
    }

    @Override
    public String getDirectoryPathSeparator() {
        return this.FILE_RESOURCE_PATH_SEPARATOR;
    }

    @Override
    public String getFileUrlPrefix() {
        return this.IMAGE_URL_PREFIX;
    }

    @Override
    public String getStorageDirectoryPath() {
        return this.IMAGE_DIRECTORY_PATH;
    }

    @Override
    public String[] getSupportedFileTypeNames() {
        return this.SUPPORTED_IMAGE_TYPES;
    }


}
